package com.qkbb.admin.kuibu.qkbb.imageloader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.R.mipmap;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;

/**
 * @author DigHammer
 * */

public class ImageLoader {

	private static final String TAG = "Dig.ImageLoader";
	// 内存缓存
	private LruMemoryCache mMemoryCache = LruMemoryCache.getInstance();
	// 下载图片所使用的线程池
	private ExecutorService mExecutorService;
	// 文件缓存
	public static DiskLruCache sDiskLruCache;
	// SD卡分配的存储大小
	private static final int DISK_CACHE_SIZE = 1024 * 1024 * 50;// 50MB
	// 单利模式
	private static ImageLoader instance = null;
	// 监听图片下载完成事件
	private OnImageDownloadedListener mListener;

	private Context mContext;

	public synchronized static ImageLoader getInstance(Context context) {
		if (instance == null) {
			instance = new ImageLoader(context);
		}
		return instance;
	}

	private ImageLoader(Context context) {
		this.mContext = context;
		// 获取图片缓存路径
		String cachePath = FileUtil.getImageCacheDirPath();
		// 实例化DiskLruCache
		if (cachePath != null) {
			Log.e("执行sDiskLruCache","sDiskLruCache");
			File cacheDir = new File(cachePath);
			sDiskLruCache = DiskLruCache.openCache(cacheDir, DISK_CACHE_SIZE);
		}
		mExecutorService = Executors.newFixedThreadPool(2);
	}

	/** 当loadMode为false的时候，表示仅仅从内存中获取对象 */
	public void loadImage(String imagename,String url, ImageView imageView, boolean loadMode) {
		Bitmap bitmap = mMemoryCache.getBitmapFromMemCache(imagename);
		Log.e("执行loadImage","loadImage");
        boolean flage=(bitmap==null);
        Log.e("flage",flage+"");
		if (bitmap != null & mListener != null) {
			Log.e("执行onImageloaded","onImageloaded");
			mListener.onImageloaded(bitmap, imageView);
		} else if (!loadMode) {
			Log.e("执行mExecutorService","mExecutorService.submit");
			mExecutorService.submit(new BitmapLoader(imagename,url, imageView));
		}
	}

	/**
	 * 
	 * 加载图片
	 * */
	private Bitmap loadBitmap(String imagename, String url,ImageView imageView) {
		// 首先判断SD卡缓存中是否有图片
		Bitmap b = null;
		if (FileUtil.hasSDCard()) {
			if (sDiskLruCache != null) {
				b = sDiskLruCache.get(imagename);
                boolean flage=(b==null);
			}
		}
		if (b != null) {
			return b;
		}
		// 从网络上下载图片
		b = downloadBitmp(url, imageView);
        Log.e("从网络上下载图片","从网络上下载图片");
		// 写入SD卡缓存
		if (FileUtil.hasSDCard() && FileUtil.isSDHasFree()) {
			if (sDiskLruCache != null & b != null) {
                Log.e("写入SD卡缓存","写入SD卡缓存");
				sDiskLruCache.put(imagename, b);
			}
		}
		return b;
	}

	/**
	 * 
	 * 从网络下载图片
	 * **/
	private Bitmap downloadBitmp(String url, ImageView imageView) {
		Bitmap bitmap = null;
		Activity activity = (Activity) imageView.getContext();
		// 判断是否有网络连接
		if (!HttpUtil.hasInternet(mContext)) {
			activity.runOnUiThread(new InformUiThreadUpdate(
					OnImageDownloadedListener.NO_NET));
			return null;
		}
		// 解决url中文乱码问题，这个地方很重要。
        Log.e("realUrl",url);
		URL imageUrl = null;
		InputStream is = null;
		HttpURLConnection conn = null;
		// 下面还要主要捕获异常，方便我们对异常情况的处理
		try {
			imageUrl = new URL(url);
		} catch (MalformedURLException e) {
			if (mListener != null) {
				activity.runOnUiThread(new InformUiThreadUpdate(
						OnImageDownloadedListener.URL_FORMAT_ERROR));
			}
			return null;
		}
		try {
			conn = (HttpURLConnection) imageUrl.openConnection();
		} catch (IOException e) {
			if (mListener != null) {
				activity.runOnUiThread(new InformUiThreadUpdate(
						OnImageDownloadedListener.CONN_TIME_OUT));
			}

			return null;
		}
		// 设置连接和读取超时时间
		conn.setConnectTimeout(30000);
		conn.setReadTimeout(30000);
		// 设置支持重定向
		conn.setInstanceFollowRedirects(true);
		try {
			// 获取输入流
			is = conn.getInputStream();
		} catch (IOException e) {
			if (mListener != null) {
				activity.runOnUiThread(new InformUiThreadUpdate(
						OnImageDownloadedListener.READ_TIME_OUT));
			}
			return null;
		}
		// 将输入流转换成bitmap对象
		bitmap = BitmapFactory.decodeStream(is);
		try {
			// 关闭输入流，以免内存泄露
			is.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return bitmap;

	}

	class BitmapLoader implements Runnable {

		private String mUrl;
		private String mImagename;
		private ImageView mImageView;

		public BitmapLoader(String imagename,String url, ImageView imageView) {
			this.mImageView = imageView;
			this.mUrl = url;
			this.mImagename=imagename;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			Bitmap bitmap = loadBitmap(mImagename,mUrl, mImageView);
			if (bitmap == null) {
				return;
			}
			mMemoryCache.addBitmapToMemoryCache(mImagename, bitmap);
			Activity activity = (Activity) mImageView.getContext();
			// 主线程更新，这里不能直接调用接口对象中onImageloaded方法
			// 不然不能更新UI，因为这里不是主线程。
			activity.runOnUiThread(new InformUiThreadUpdate(bitmap, mImageView));

		}
	}

	/**
	 * 
	 * 调用接口方法，通知UI线程进行相应的操作
	 * */
	class InformUiThreadUpdate implements Runnable {

		private Bitmap mBitmap;

		private ImageView mImageView;

		private int mOperation = -1;

		public InformUiThreadUpdate(Bitmap bitmap, ImageView imageView) {
			this.mImageView = imageView;
			this.mBitmap = bitmap;
		}

		public InformUiThreadUpdate(int operation) {
			this.mOperation = operation;

		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (mListener != null) {
				if (mOperation == -1) {
					mListener.onImageloaded(mBitmap, mImageView);

				} else {
					mListener.onDowndloadFailure(mOperation);
				}

			}
		}
	}

	public void setOnImageDownloadListener(OnImageDownloadedListener listener) {
		this.mListener = listener;
	}

	/** 下载接口监听处理 */
	public interface OnImageDownloadedListener {

		public static final int NO_NET = 0;

		public static final int URL_FORMAT_ERROR = 1;

		public static final int CONN_TIME_OUT = 2;

		public static final int READ_TIME_OUT = 3;

		void onImageloaded(Bitmap b, ImageView imageView);

		void onDowndloadFailure(int type);
	}

}
